use std::sync::{Arc, Mutex};
use anyhow::Result;

use crate::di::{ServiceContainer, services::ConfigService};
use crate::config::{Configs, Server, DataBase, Log, Jwt, Cert};

/// 依赖注入系统演示
/// 
/// 这个模块展示了如何使用我们实现的依赖注入系统

/// 创建演示配置
fn create_demo_config() -> Configs {
    Configs {
        server: Server {
            name: "demo-server".to_string(),
            address: "127.0.0.1:8080".to_string(),
            ssl: false,
        },
        database: DataBase {
            database_url: "sqlite::memory:".to_string(),
        },
        log: Log {
            filter_level: "info".to_string(),
            with_ansi: true,
            to_stdout: true,
            directory: "./logs".to_string(),
            file_name: "demo.log".to_string(),
            rolling: "daily".to_string(),
        },
        jwt: Jwt {
            jwt_secret: "demo_secret".to_string(),
            jwt_exp: 3600,
        },
        cert: Cert {
            cert: "demo.pem".to_string(),
            key: "demo.key".to_string(),
        },
    }
}

/// 演示服务A
#[derive(Debug)]
pub struct ServiceA {
    config: Arc<ConfigService>,
    name: String,
    list: Mutex<Vec<String>>,
}

impl ServiceA {
    pub fn new(config: Arc<ConfigService>) -> Self {
        Self {
            config,
            name: "ServiceA".to_string(),
            list: Mutex::new(Vec::new()),
        }
    }
    
    pub fn get_info(&self) -> String {
        format!(
            "{} - Server: {}, Database: {}",
            self.name,
            self.config.config().server.name,
            self.config.config().database.database_url
        )
    }
    pub fn add_info(&self, info: String) -> Result<String> {
        let mut list = self.list.lock()
            .map_err(|_| anyhow::anyhow!("Failed to acquire lock on list"))?;
        list.push(info);
        Ok(format!(
            "{} - Server: {}, Database: {}",
            self.name,
            self.config.config().server.name,
            self.config.config().database.database_url
        ))
    }
}

/// 演示服务B
#[derive(Debug)]
pub struct ServiceB {
    service_a: Arc<ServiceA>,
    config: Arc<ConfigService>,
    name: String,
}

impl ServiceB {
    pub fn new(service_a: Arc<ServiceA>, config: Arc<ConfigService>) -> Self {
        Self {
            service_a,
            config,
            name: "ServiceB".to_string(),
        }
    }
    
    pub fn get_combined_info(&self) -> String {
        format!(
            "{} depends on: [{}] - JWT Secret: {}",
            self.name,
            self.service_a.get_info(),
            self.config.config().jwt.jwt_secret
        )
    }
}

/// 演示服务C（瞬态服务）
#[derive(Debug)]
pub struct ServiceC {
    id: u64,
    timestamp: std::time::SystemTime,
}

impl ServiceC {
    pub fn new() -> Self {
        use std::sync::atomic::{AtomicU64, Ordering};
        static COUNTER: AtomicU64 = AtomicU64::new(0);
        
        Self {
            id: COUNTER.fetch_add(1, Ordering::SeqCst),
            timestamp: std::time::SystemTime::now(),
        }
    }
    
    pub fn get_info(&self) -> String {
        format!("ServiceC - ID: {}, Created: {:?}", self.id, self.timestamp)
    }
}

/// 运行依赖注入演示
pub async fn run_demo() -> Result<()> {
    println!("🚀 依赖注入系统演示开始");
    println!("{}", "=".repeat(50));
    
    // 1. 创建容器
    println!("📦 创建服务容器...");
    let container = ServiceContainer::new();
    
    // 2. 注册配置服务（单例）
    println!("⚙️  注册配置服务（单例）...");
    let config = create_demo_config();
    container.register_singleton::<ConfigService, _>(move |_| {
        Ok(ConfigService::new(config.clone()))
    })?;
    
    // 3. 注册ServiceA（单例，依赖配置服务）
    println!("🔧 注册ServiceA（单例，依赖配置服务）...");
    container.register_singleton::<ServiceA, _>(|container| {
        let config_service = container.resolve::<ConfigService>()?;
        Ok(ServiceA::new(config_service))
    })?;
    
    // 4. 注册ServiceB（单例，依赖ServiceA和配置服务）
    println!("🔧 注册ServiceB（单例，依赖ServiceA和配置服务）...");
    container.register_singleton::<ServiceB, _>(|container| {
        let service_a = container.resolve::<ServiceA>()?;
        let config_service = container.resolve::<ConfigService>()?;
        Ok(ServiceB::new(service_a, config_service))
    })?;
    
    // 5. 注册ServiceC（瞬态）
    println!("🔧 注册ServiceC（瞬态）...");
    container.register_transient::<ServiceC, _>(|_| {
        Ok(ServiceC::new())
    })?;
    
    println!("\n✅ 所有服务注册完成！");
    println!("📊 容器中共有 {} 个服务", container.service_count());
    
    // 6. 演示服务解析
    println!("\n🔍 开始解析服务...");
    
    // 解析配置服务
    let config_service = container.resolve::<ConfigService>()?;
    println!("✅ 配置服务解析成功: {}", config_service.config().server.name);
    
    // 解析ServiceA
    let service_a = container.resolve::<ServiceA>()?;
    service_a.add_info("aa".to_string())?;
    println!("✅ ServiceA解析成功: {}", service_a.get_info());
    
    // 解析ServiceB
    let service_b = container.resolve::<ServiceB>()?;
    println!("✅ ServiceB解析成功: {}", service_b.get_combined_info());
    
    // 7. 演示单例行为
    println!("\n🔄 验证单例行为...");
    let config_service2 = container.resolve::<ConfigService>()?;
    let is_same = Arc::ptr_eq(&config_service, &config_service2);
    println!("✅ 配置服务是否为同一实例: {}", is_same);
    
    let service_a2 = container.resolve::<ServiceA>()?;
    let is_same_a = Arc::ptr_eq(&service_a, &service_a2);
    println!("✅ ServiceA是否为同一实例: {}", is_same_a);
    
    // 8. 演示瞬态行为
    println!("\n🔄 验证瞬态行为...");
    let service_c1 = container.resolve::<ServiceC>()?;
    let service_c2 = container.resolve::<ServiceC>()?;
    let service_c3 = container.resolve::<ServiceC>()?;
    
    println!("✅ ServiceC实例1: {}", service_c1.get_info());
    println!("✅ ServiceC实例2: {}", service_c2.get_info());
    println!("✅ ServiceC实例3: {}", service_c3.get_info());
    
    let all_different = !Arc::ptr_eq(&service_c1, &service_c2) 
        && !Arc::ptr_eq(&service_c2, &service_c3) 
        && !Arc::ptr_eq(&service_c1, &service_c3);
    println!("✅ 所有ServiceC实例都不同: {}", all_different);
    
    // 9. 演示多线程安全
    println!("\n🧵 验证多线程安全...");
    let container = Arc::new(container);
    let mut handles = Vec::new();
    
    for i in 0..5 {
        let container_clone = Arc::clone(&container);
        let handle = tokio::spawn(async move {
            let config_service = container_clone.resolve::<ConfigService>().unwrap();
            let service_b = container_clone.resolve::<ServiceB>().unwrap();
            
            println!("🧵 线程 {} - 配置服务: {}", i, config_service.config().server.name);
            println!("🧵 线程 {} - ServiceB: {}", i, service_b.get_combined_info());
            
            // 模拟一些工作
            tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
            
            i
        });
        handles.push(handle);
    }
    
    // 等待所有线程完成
    for handle in handles {
        handle.await?;
    }
    
    println!("\n✅ 多线程测试完成！");
    
    // 10. 性能测试
    println!("\n⚡ 性能测试...");
    let start = std::time::Instant::now();
    
    for _ in 0..1000 {
        let _config = container.resolve::<ConfigService>()?;
        let _service_a = container.resolve::<ServiceA>()?;
        let _service_b = container.resolve::<ServiceB>()?;
    }
    
    let duration = start.elapsed();
    println!("✅ 1000次服务解析耗时: {:?}", duration);
    println!("✅ 平均每次解析耗时: {:?}", duration / 1000);
    
    println!("\n🎉 依赖注入系统演示完成！");
    println!("{}", "=".repeat(50));
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_demo() {
        run_demo().await.unwrap();
    }
}
